package com.MedDroid.entities;

import com.MedDroid.entities.database.DatabaseField;
import com.MedDroid.entities.database.DatabaseRow;
import android.content.Context;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Created with IntelliJ IDEA.
 * User: Romen
 * Date: 19/11/13
 * Time: 9:41 PM
 * Description: Maintains a simple row,field data structure with explicit class objects for each entry. All values are stored as strings.
 */
public class Database
{
	//PRIVATE VARIABLES
	ArrayList<DatabaseRow> Entries;

	//PUBLIC VARIABLES
	public static final String Separator = "___";
	public static String NewLine = "%%%";

	//CONSTRUCTOR
	public Database()
	{
		Entries = new ArrayList<DatabaseRow>();
		//NewLine = System.getProperty("line.separator");
	}

	//GET METHODS
	public ArrayList<DatabaseRow> getDatabase()
	{
		return Entries;
	}

	public String getField(int Row, String FieldName)
	{
		return Entries.get(Row).getValue(FieldName);
	}

	public String getField(String RowLabel, String FieldName)
	{
		DatabaseRow Row = getRowbyLabel(RowLabel);
		if (Row != null)
		{
			return Row.getValue(FieldName);
		}

		return "";
	}

	private DatabaseRow getRowbyLabel(String Label)
	{
		for (DatabaseRow Row : Entries)
		{
			if (Row.getLabel().equalsIgnoreCase(Label))
			{
				return Row;
			}
		}
		return null;
	}

	//SEARCH METHODS
	public DatabaseRow findRow(String FieldName, String Value)
	{
		for (DatabaseRow Row : Entries)
		{
			if (Row.getValue(FieldName).equalsIgnoreCase(Value))
			{
				return Row;
			}
		}
		return null;
	}

	//ROW METHODS
	public int addRow(String Label)
	{
		int Index = Entries.size();
		Entries.add(new DatabaseRow(Index,Label));
		return Index;
	}

	public int addRow(DatabaseRow NewRow)
	{
		int Index = Entries.size();
		NewRow.setIndex(Index);
		Entries.add(NewRow);
		return Index;
	}

	public void removeRow(int RowIndex)
	{
		Entries.remove(RowIndex);
	}

	public void removeRow(DatabaseRow Row)
	{
		Entries.remove(Row);
	}

	public void replaceRow(String FieldName, String Value, DatabaseRow NewRow)
	{
		int Index = Entries.indexOf(findRow(FieldName,Value));
		if (Index != -1)
		{
			Entries.set(Index, NewRow);
		}
		else
		{
			Entries.add(NewRow);
		}
	}

	public void replaceRow(DatabaseRow OldRow, DatabaseRow NewRow)
	{
		Entries.set(Entries.indexOf(OldRow), NewRow);
	}

	//FIELD METHODS
	public boolean addField(int Row, String FieldName, String Value)
	{
		if (Row >= Entries.size())
		{
			return false;
		}
		else
		{
			Entries.get(Row).addField(new DatabaseField(FieldName,Value));
			return true;
		}
	}

	//DATABASE METHODS
	public void clearDatabase()
	{
		Entries = new ArrayList<DatabaseRow>();
	}

	public void encrypt()
	{
		for (DatabaseRow Row : Entries)
		{
			Row.encrypt();
		}
	}

	public void decrypt()
	{
		for (DatabaseRow Row : Entries)
		{
			Row.decrypt();
		}
	}

	//IMPORT AND EXPORT METHODS
	public boolean exportData(Context C, String FileName)
	{
		String OutputString = "";
		//Build OutputString
		for (DatabaseRow Row : Entries)
		{
			String RowString = "";
			RowString += Row.getLabel() + Separator;
			RowString += Row.getSize() + Separator;
			for (DatabaseField Field : Row.getFields())
			{
				String FieldString = Field.getName() + Separator + Field.getValue() + Separator;
				RowString += FieldString;
			}
			RowString += NewLine;
			OutputString += RowString;
		}

		//Write OutputString
		try
		{
			FileOutputStream Output = C.openFileOutput(FileName, Context.MODE_PRIVATE);
			Output.write(OutputString.getBytes());
			Output.close();
		}
		catch (IOException E)
		{
			//IO error
			E.printStackTrace();
			return false;
		}

		//Nothing went wrong
		return true;
	}

	public boolean importData(Context C, String FileName)
	{
		StringBuffer InputStringBuffer = new StringBuffer("");
		//Read InputString
		try
		{
			byte[] buffer = new byte[1024];
			FileInputStream Input = C.openFileInput(FileName);
			while (Input.read(buffer) != -1)
			{
				InputStringBuffer.append(new String(buffer));
			}
		}
		catch (IOException E)
		{
			//IO error
			E.printStackTrace();
			return false;
		}
		String[] InputLines = InputStringBuffer.toString().split(NewLine);

		//Build Database from InputString
		clearDatabase();
		for (String Line : InputLines)
		{
			String[] Fields = Line.split(Separator);
			int NewRow = addRow(Fields[0]);
			int FieldCount = Integer.parseInt(Fields[1]);
			for (int i=0; i<FieldCount; i++)
			{
				addField(NewRow,Fields[2+i*2],Fields[3+i*2]);
			}
		}

		//Nothing went wrong
		return true;
	}
}
